#!/bin/sh


echo ============================== special shell variables ==============================
# $1 - $9       these variables are the positional parameters. (the 1,2, ... parameters)
# $0            the name of the command currently being executed. (contain the path)
# $#            the number of positional arguments given to this invocation of the shell.
# $?            the exit status of the last command executed, 0 for success, otherwise non-zero

# $$            the process number of this shell - useful for including in filenames, to make them unique.
# $!            the process id of the last command run in the background.
# $-            the current options supplied to this invocation of the shell.

# $*            a string containing all the arguments to the shell, starting at $1.		---- Notice!
# $@            same as above, except when quoted.
# $* and $@ when unquoted are identical and expand into the arguments.

# "$*" is a single word, comprising all the arguments to the shell, joined together with spaces. For example '1 2' 3 becomes "1 2 3".
# "$@" is identical to the arguments received by the shell, the resulting list of words completely match what was given to the shell. For example '1 2' 3 becomes "1 2" "3"

echo "the command you run : $0 $@"		# echo -e "xxx\tyyy" to print \t or \n ...
echo "total parameters:  $#"
echo "the command : $0"
echo "the first param : $1"
echo "the second param : $2"
echo "all parameters : "
for i in $* ; do
	echo $i
done

echo ============================== shell variables ==============================

declare -i idx=0        #integer var
declare -a array        #array 
for i in $@; do
    array[idx]=$i		#record the params
    idx=idx+1			#no need let idx+=1
done

echo ${array[0]}		 #the first elem of array[]
echo ${array[1]}

for i in ${array[@]}; do		# traverse the array
    echo $i
done

## array
array=("aaa" "bbb" "ccc" "ddd")
echo "the array is '${array[@]}'"
echo "the length of array: " ${#array[@]}
echo "the second item is ${array[1]}"
echo "slice (1->2):" ${array[@]:1:2}
echo "slice (start from 2) : " ${array[@]:2}
echo "slice (to 2) : " ${array[@]::2}

for name in ${foo[@]}	# traverse the items
do
echo $name
done

for((i=0;i<${#foo[@]};i++))	# another method to traverse
do
echo ${foo[$i]}
done


echo ============================== conditional branch ==============================

str="hello"
if [ $str = "hello" ]; then
	echo "command 1" 
elif [ str = "world" ]; then
	echo "command 2"
else
	echo "other command"
fi

SYSTEM=`uname -s`					# get the type of os
if [ $SYSTEM = "Linux" ] ; then
	echo "Linux" 
elif [ $SYSTEM = "FreeBSD" ] ; then   
	echo "FreeBSD" 
elif [ $SYSTEM = "Solaris" ] ; then 
	echo "Solaris" 
else 
	echo "What?" 
fi

if [ "$str" = "hello" ] || [ "$str2" = "world" ] ; then    # or &&
    echo "ok"
fi

if [ -d mydir ]; then echo "mydir exist"; fi
if [ ! -d mydir ]; then echo "mydir not exist"; fi
if [ -f template.sh ]; then
    echo "template.sh exist and is a regular file"
fi

str1="hello"
str2="world";
if [ x$str1 = xhello -a x$str2 != xhello ]; then echo "ok"; fi	# -a: and, -o: or


echo ============================== for loop ============================== 

# walk through file list
for f in `ls`; do
    echo "file : $f"
done

for i in  /proc/sys/net/*/conf/; do echo $i;done
# /proc/sys/net/ipv4/conf/
# /proc/sys/net/ipv6/conf/


# walk through numbers
for i in `seq 1 10`;do        # `seq 10` is the equal
	echo $i
done

for((i=1;i<10;i++));do        # like c language
	echo $i
done

# walk through vars
var="apple pear banana"
for i in $var; do
    echo $i
done

for i in China India Tailand; do
	echo $i
done

echo ============================== while loop ============================== 
# while expression; do
# 	statements
# done

i=0
end=5
while [ $i -lt $end ]; do
    echo $i
    let i+=1	# or ((i++))
done

echo ============================== case ============================== 

# case $varname in
#     pattern1 | pattern2)
#         command1
#         ......
#         commandN
#         ;;
#     pattern3)
#         commandX
#         ;;
#     *)       #default
#         default_command
#         ;;
# esac

NOW=$(date +"%a") 
case $NOW in 
	Mon) echo "start working";; 
	Tue|Wed|Thu|Fri) echo "working hard";;
	Sat|Sun) echo "rest";; 
	*) ;; 
esac

echo ============================== function ============================== 
# variables defined in shell is global, it's valid from defined to shell terminated or explictly deleted
function myfun()
{
    echo $mf_var
}

echo "mf_var : $mf_var"
mf_var=100						# now you can use mf_var in myfun()
myfun							# call myfun()
echo "mf_var : $mf_var"

echo ============================== awk ============================== 

awk -F : '{printf(".word 0x%s #%s", $2, $5)}' testfile



# #字符串分割成数组  

# var=`awk -F',' '{print $2}' "aaa,bbb,ccc"'
# echo $var

# var=`echo "aaa,bbb,ccc"|awk -F ',' '{print $2}' `

# var=`echo "aaa,bbb,ccc" | awk -F',' '{print $0}' | sed "s/,/ /g"`
# 这样得出var的值是：aaa bbb ccc
# 用sed把字符串的‘,’符号换成空格。for 变量 in 很多个以空格分隔值

 
# a="one,two,three,four"
# OLD_IFS="$IFS"  #备份默认的分隔符，使用完后将之恢复默认
# IFS=","         #分隔符
# arr=($a)        # arr=($a)用于将字符串$a分割到数组$arr
# IFS="$OLD_IFS"    
# for s in ${arr[@]}    # ${arr[@]}存储整个数组
# do
#  echo "$s" 
# done


# http://www.thegeekstuff.com/2011/07/bash-for-loop-examples/





# # Makefile：
# # all:
# #     for d in `ls`; do echo $$d ; done    #必须在一行写完,或者可以用\表示断行，总之不可以分行写




echo ============================== grep ==============================
# -v, --invert-match, Invert the sense of matching, to select non-matching lines.
ls | grep 'tmp' -v							# files not contain 'tmp'
find -name "*.c" | xargs grep 'my_t' -n		# -n, print the line-number in file

find -name "*.c" | xargs grep 'hello' | awk -F : '{print $1}'		# just print the first column (the file name)
find -name "*.c" | xargs grep 'hello' -n | awk -F : '{print $1}' | uniq		# merge the same row
cat table | sort | uniq												# first sort, then merge the same item



echo ============================== sed ==============================
sed '/abcd/d' file1


echo ============================== find ==============================
# find .c or .h file
find ../c/ -name "*.c" -o -name "*.h"
find ../c/ -name "*.c" -o -name "*.h" | xargs grep 'int' -n
# find regular file "Makefile" in current dir
find -name "Makefile" -type f
# find in ./sk-chang, but ignore the ./sk-chang/google (google can be a dir or a file), but never ignore the ./sk-chang/config/google
find ./sk-chang -path "./sk-chang/google" -prune -o -print
# find in ./sk-chang but ignore the ./sk-chang/google and ./sk-chang/config, -type d means find directory
find ./sk-chang \( -path "./sk-chang/google" -o -path "./sk-chang/config" \) -prune -o -type d -print
# find regualr file "demo.rst" in ./sk-chang, ignore the ./sk-chang/google and ./sk-chang/config dir, the result may be  "./sk-chang/docs/slide/demo.rst"
find ./sk-chang \( -path "./sk-chang/google" -o -path "./sk-chang/config" \) -prune -o -type f -name "demo.rst" -print
# find and ignore all ".svn" recursively in current dir
find . -path "*/.svn" -prune -o -print
# del all .svn directory 
find -type d -name ".svn" | xargs rm -rf
# find files modified more recently than template.sh
find -newer template.sh


echo ============================== path & file ==============================
# get the dirname, filename and suffix
dirname /tmp/hello/world.v		# /tmp/hello
dirname hello.v					# .
basename /tmp/hello/world.v		# world.v
basename /tmp/hello/world.v .v	# world (strip the suffix .v)

file="world.v"
name=${file%.*}
suffix=${file##*.}
echo "name: $name, suffix: $suffix"

echo ============================== useful patterns ==============================
# volume of dirs (exclude the hidden dirs)
ls -l | grep '^d' | awk '{print $9}' | xargs du -sh

# download files according to the links in filelist
# wget -i filelist

# for echo
echo -e "hello\nworld"		# -e : enable interpretation of backslash escapes
echo -e "Error : xxxx, quit \n yyyy " | tee -a run.log    #  write to standard output and append to run.log
echo -n "hello"		# do not output the trailing newline, the same as
echo -e "hello\c"

# cp -L, --dereference, always follow symbolic links in SOURCE
cp -rL ~/test/ tmp	# copy the dereference files in test, not the symbol link self


# for -q param means quit : not write anything to standard output or not write the detail info
diff -q t1.sh t2.sh	# report only when files differ, the result is : Files t1.sh and t2.sh differ
diff -y t1.sh t2.sh	# output side-by-side
grep "hello" template.sh -q; echo $?	# no output, used to check whether template.sh has "hello" or not (0 means has)



# never place code after here
i=0
while [ $i -lt 10 ]; do
	echo $i
	if [ $i = 5 ]; then
		kill $$
	fi
	((i++))
	sleep 0.1
done

	
